﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Controls.Ribbon;
using SHomeWorkshop.LunarConcept.Controls;
using System.Xml;
using SHomeWorkshop.LunarConcept.Tools;
using SHomeWorkshop.LunarConcept.ModifingManager;
using System.Windows;

namespace SHomeWorkshop.LunarConcept.Commands
{
    /// <summary>
    /// 创建时间：2011年12月30日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：在当前EdirorManager中的处于MainSelected状态的PageEditor后部添加一个新的PageEditor，
    ///           并使新PageEditor成为MainSelected。
    /// </summary>
    public static class InsertNewPageEditorCommand
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// [静态][构造方法]
        /// 
        /// ——此方法会初始化并向WPF系统注册一个RoutedUICommand。
        /// </summary>
        static InsertNewPageEditorCommand()//类型构造器
        {
            routedUICmd = new RoutedUICommand(
                "InsertNewPageEditorCommand",
                "InsertNewPageEditorCommand",
                typeof(InsertNewPageEditorCommand),//创建RoutedUICommand对象
                null);//本程序考虑支持“命令模式”因此，这些命令完全没有必要直接支持快捷键。

            routedUICmd.InputGestures.Add(new KeyGesture(Key.P,
                ModifierKeys.Control | ModifierKeys.Shift, "Ctrl + Shift + P"));

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        #endregion

        #region 字段与属性===================================================================================================

        private static CommandBinding cmdBinding = new CommandBinding();
        /// <summary>
        /// 用在主窗口CommandBindings集合中的命令绑定。
        /// 
        /// 它的Command是RoutedUICommand。
        /// ——因此，RoutedUICommand是否可以运行将由CmdBinding的CanExecute事件决定。
        /// ——而且，RoutedUICommand的执行也是通过CmdBinding的Execute事件来进行的。
        /// </summary>
        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        private static RoutedUICommand routedUICmd;
        /// <summary>
        /// [只读静态属性]表示在WPF系统中注册的一个RoutedUICommand。
        /// ——必须和CommandBinding配合才能使用。
        ///     CommandBinding要添加到主窗口的CommandBindings集合中；
        ///     RoutedUICommand则要向WPF系统注册。
        ///     
        /// ★说明：使用静态属性是因为这样在Xaml代码中比较便于绑定。
        /// </summary>
        public static RoutedUICommand RoutedUICmd
        {
            get { return routedUICmd; }
        }

        #endregion

        #region 方法=========================================================================================================

        /// <summary>
        /// 判断命令是否可以执行。
        /// ——由于可以直接调用Execute()方法，因此，即使被禁用，也不是不能执行相关功能！！！
        /// </summary>
        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;//总是可用的。
        }

        /// <summary>
        /// 命令被触发时，会调用本事件处理器方法。
        /// ——本方法实际上是调用ExeCute()这个静态方法来实现特定功能。
        /// </summary>
        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            LunarMessage.Warning(Execute());
        }

        /// <summary>
        /// [公开静态方法]即使此命令处于禁用状态，也可以通过代码调用此方法来执行特定任务！！！
        /// 
        /// 当被绑定的命令被调用（触发）时，会引发cmdBinding_Executed事件。
        /// 在cmdBinding_Executed事件处理器方法中已添加了调用Execute()方法的代码。
        /// 
        /// ——因此，触发命令，就相当于调用此方法！！！
        /// </summary>
        public static string Execute(XmlNodeList pageXmlNodeList = null)
        {
            if (Globals.MainWindow == null) return "　　未找到Globals.MainWindow。";

            EditorManager manager = Globals.MainWindow.EditorManager;
            if (manager == null) return "　　未找到页面管理器。";

            XmlNode pageSetNode = manager.XmlDocument.DocumentElement.SelectSingleNode(XmlTags.PageSetTag);

            if (pageSetNode == null)
            {
                pageSetNode = manager.XmlDocument.DocumentElement.
                    AppendXmlAsChild(string.Format("<{0} />", XmlTags.PageSetTag));
            }

            if (manager.Count >= 500)
            {
                MessageBoxResult r = MessageBox.Show("　　天哪！竟然超过500页！这太难想像了。真的要继续吗？",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);

                if (r != MessageBoxResult.Yes) return string.Empty;
            }

            if (pageXmlNodeList == null || pageXmlNodeList.Count == 0)
            {
                PageEditor basePageEditor = manager.GetMainSelectedPageEditor();

                if (basePageEditor == null) basePageEditor = manager.LastPageEditor;

                if (basePageEditor == null)
                {
                    //当前还没有任何页面（都被删除了）。直接添加新页面。

                    XmlNode newPageNode = pageSetNode.AppendXmlAsChild(string.Format("<{0} />", XmlTags.PageTag));

                    PageEditor newPageEditor = new PageEditor(manager);
                    newPageEditor.XmlData = newPageNode;
                    newPageEditor.NewID();
                    newPageEditor.PaperSizeText = basePageEditor.PaperSizeText;

                    manager.AddPageEditor(newPageEditor);

                    ModifingInfo info = new ModifingInfo();

                    //记录操作前被选定的所有PageEditor的ID。
                    List<PageEditor> oldSelectedPageEditorList = manager.GetSelectedPageEditorsList();
                    manager.GetSelectedWidgetStatus_Old(info);
                    foreach (PageEditor pe in oldSelectedPageEditorList)
                    {
                        info.AddPageEditorID_OldSelected(pe.Id);
                        if (pe.IsMainSelected)
                        {
                            info.OldMainSelectedPageEditorID = pe.Id;
                        }

                        if (pe.IsSelected) pe.IsSelected = false;
                    }
                    manager.GetSelectedWidgetStatus_New(info);

                    info.NewMainSelectedPageEditorID = newPageEditor.Id;

                    info.ModifingDescription = "添加新页";

                    ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

                    Action actAddPageEditor = new Action(ActionType.PageEditorAdded, newPageEditor.Id, 0, null,
                        newPageEditor.XmlData.OuterXml);
                    mi.AddAction(actAddPageEditor);

                    manager.RegisterModifingItem(mi);

                    newPageEditor.IsMainSelected = true;

                    manager.RefreshPaginations();
                    return string.Empty;
                }
                else
                {
                    XmlNode newPageNode = null;
                    if (basePageEditor.XmlData.InsertXml(string.Format("<{0} />", XmlTags.PageTag), true))
                    {
                        newPageNode = basePageEditor.XmlData.NextSibling;
                    }

                    if (newPageNode == null) return "　　未能顺利添加新页面节点。";

                    PageEditor newPageEditor = new PageEditor(manager);
                    newPageEditor.XmlData = newPageNode;
                    newPageEditor.NewID();

                    //这个功能有时会让用户莫名其妙，还是不添加为妙。
                    //if (basePageEditor.PaperDirection != basePageEditor.MasterManager.DefPaperDirection)
                    //{
                    newPageEditor.PaperDirection = basePageEditor.PaperDirection;
                    //}
                    //这个功能有时会让用户莫名其妙，还是不添加为妙。
                    //if (basePageEditor.PaperSize != basePageEditor.MasterManager.DefPaperInfo)
                    //{
                    newPageEditor.PaperSize = basePageEditor.PaperSize;
                    newPageEditor.PaperSizeText = basePageEditor.PaperSizeText;
                    //}

                    newPageEditor.AssistGridForm = basePageEditor.AssistGridForm;

                    int newIndex = manager.InsertAfter(basePageEditor, newPageEditor);

                    ModifingInfo info = new ModifingInfo();

                    //记录操作前被选定的所有PageEditor的ID。
                    List<PageEditor> oldSelectedPageEditorList = manager.GetSelectedPageEditorsList();
                    manager.GetSelectedWidgetStatus_Old(info);
                    foreach (PageEditor pe in oldSelectedPageEditorList)
                    {
                        info.AddPageEditorID_OldSelected(pe.Id);
                        if (pe.IsMainSelected)
                        {
                            info.OldMainSelectedPageEditorID = pe.Id;
                        }

                        if (pe.IsSelected) pe.IsSelected = false;
                    }
                    manager.GetSelectedWidgetStatus_New(info);

                    info.ModifingDescription = "添加新页";

                    //记录操作后被选定的（其实就是新添加的PageEditor的ID）。
                    info.NewMainSelectedPageEditorID = newPageEditor.Id;
                    newPageEditor.IsMainSelected = true;

                    ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

                    Action actAddPageEditor = new Action(ActionType.PageEditorAdded, newPageEditor.Id, newIndex, null,
                        newPageEditor.XmlData.OuterXml);
                    mi.AddAction(actAddPageEditor);

                    manager.RegisterModifingItem(mi);
                    manager.RefreshPaginations();
                    manager.TryToDisplayPageEditor(newPageEditor, false);

                    manager.MasterWindow.RefreshPageView();

                    return string.Empty;
                }
            }
            else
            {
                ModifingInfo info = new ModifingInfo();

                //记录操作前被选定的所有PageEditor的ID。
                List<PageEditor> oldSelectedPageEditorList = manager.GetSelectedPageEditorsList();

                info.ModifingDescription = "粘贴新页";

                ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

                PageEditor basePageEditor = manager.GetMainSelectedPageEditor();

                if (basePageEditor == null) basePageEditor = manager.LastPageEditor;
                else info.OldMainSelectedPageEditorID = basePageEditor.Id;

                foreach (PageEditor pe in oldSelectedPageEditorList)
                {
                    info.AddPageEditorID_OldSelected(pe.Id);

                    if (pe.IsSelected) pe.IsSelected = false;
                }

                if (basePageEditor == null)
                {
                    //当前还没有任何页面（都被删除了）。直接添加新页面。
                    //截止2013年9月14日还不起作用，因为Paste()方法目前禁止不选定任何页面就粘贴。
                    //manager.GetSelectedWidgetStatus_Old(info);
                    //PageEditor firstNewPage = null;

                    //foreach (XmlNode node in pageXmlNodeList)
                    //{
                    //    XmlNode newPageNode = pageSetNode.AppendXmlAsChild(node.OuterXml);

                    //    PageEditor newPageEditor = new PageEditor(manager);
                    //    newPageEditor.XmlData = newPageNode;
                    //    newPageEditor.NewID();

                    //    manager.AddPageEditor(newPageEditor);

                    //    Action actAddPageEditor = new Action(ActionType.PageEditorAdded, newPageEditor.Id, 0, null,
                    //        newPageEditor.XmlData.OuterXml);
                    //    mi.AddAction(actAddPageEditor);

                    //    if (firstNewPage == null)
                    //    {
                    //        firstNewPage = newPageEditor;
                    //        info.NewMainSelectedPageEditorID = firstNewPage.Id;
                    //        firstNewPage.IsMainSelected = true;
                    //    }
                    //    else
                    //    {
                    //        newPageEditor.IsSelected = true;
                    //    }

                    //    basePageEditor = newPageEditor;
                    //}

                    //manager.GetSelectedPageEditorStatus(info);
                    //manager.RegisterModifingItem(mi);
                    //manager.RefreshPaginations();

                    return string.Empty;
                }
                else
                {
                    PageEditor firstNewPage = null;

                    foreach (XmlNode node in pageXmlNodeList)
                    {
                        XmlNode newPageNode = null;
                        if (basePageEditor.XmlData.InsertXml(node.OuterXml))
                        {
                            newPageNode = basePageEditor.XmlData.NextSibling;
                        }

                        if (newPageNode == null) return "　　未能顺利添加新页面节点。";

                        PageEditor newPageEditor = new PageEditor(manager);
                        newPageEditor.XmlData = newPageNode;
                        PageEditor.NewWidgetsID(newPageEditor.XmlData);
                        newPageEditor.NewID();
                        newPageEditor.AssistGridForm = basePageEditor.AssistGridForm;

                        //应保持页面自定义的页面尺寸（默认A4），粘贴页面不同于普通的插入页面。
                        //newPageEditor.PaperDirection = basePageEditor.PaperDirection;
                        //newPageEditor.PaperSize = basePageEditor.PaperSize;

                        int newIndex = manager.InsertAfter(basePageEditor, newPageEditor);

                        Action actAddPageEditor = new Action(ActionType.PageEditorAdded, newPageEditor.Id, newIndex, null,
                            newPageEditor.XmlData.OuterXml);
                        mi.AddAction(actAddPageEditor);

                        if (firstNewPage == null)
                        {
                            firstNewPage = newPageEditor;
                            //记录操作后被选定的（其实就是新添加的PageEditor的ID）。
                            info.NewMainSelectedPageEditorID = firstNewPage.Id;
                            firstNewPage.IsMainSelected = true;
                        }
                        else
                        {
                            newPageEditor.IsSelected = true;
                        }

                        basePageEditor = newPageEditor;
                    }

                    var oldMainselPageId = info.OldMainSelectedPageEditorID;
                    manager.GetSelectedPageEditorStatus(info);//这个方法会导致OldMainSelectedPageEditorID被改成和NewMainSelectedPageEditorID相同的值。
                    info.OldMainSelectedPageEditorID = oldMainselPageId;
                    manager.RegisterModifingItem(mi);
                    manager.RefreshPaginations();

                    if (firstNewPage != null)
                        manager.TryToDisplayPageEditor(firstNewPage, false);

                    manager.MasterWindow.RefreshPageView();

                    return string.Empty;
                }
            }
        }

        #endregion
    }
}
